// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

<template>
  <a-table
    size="middle"
    :loading="loading"
    :columns="isOrderUpdatable() ? columns : columns.filter(x => x.dataIndex !== 'order')"
    :dataSource="items"
    :rowKey="(record, idx) => record.id || record.name || record.usageType || idx + '-' + Math.random()"
    :pagination="false"
    :rowSelection="explicitlyAllowRowSelection || enableGroupAction() || $route.name === 'event' ? {selectedRowKeys: selectedRowKeys, onChange: onSelectChange, columnWidth: 30} : null"
    :rowClassName="getRowClassName"
    @resizeColumn="handleResizeColumn"
    style="overflow-y: auto"
  >
    <template #customFilterDropdown>
      <div style="padding: 8px" class="filter-dropdown">
        <a-menu>
          <a-menu-item v-for="(column, idx) in columnKeys" :key="idx" @click="updateSelectedColumns(column)">
            <a-checkbox :id="idx.toString()" :checked="selectedColumns.includes(getColumnKey(column))"/>
            {{ $t('label.' + String(getColumTitle(column)).toLowerCase()) }}
          </a-menu-item>
        </a-menu>
      </div>
    </template>
    <template #bodyCell="{ column, text, record }">
      <template v-if="['name', 'provider'].includes(column.key) ">
        <span v-if="['vm', 'vnfapp'].includes($route.path.split('/')[1])" style="margin-right: 5px">
          <span v-if="record.icon && record.icon.base64image">
            <resource-icon :image="record.icon.base64image" size="2x"/>
          </span>
          <os-logo v-else :osId="record.ostypeid" :osName="record.osdisplayname" size="2x" />
        </span>
        <span style="min-width: 120px" >
          <QuickView
            style="margin-left: 5px"
            :actions="actions"
            :resource="record"
            :enabled="quickViewEnabled() && actions.length > 0 && columns && ['name', 'provider'].includes(columns[0].dataIndex)"
            @exec-action="$parent.execAction"/>
          <span v-if="$route.path.startsWith('/project')" style="margin-right: 5px">
            <tooltip-button type="dashed" size="small" icon="LoginOutlined" @onClick="changeProject(record)" />
          </span>
          <span v-if="$showIcon() && !['vm', 'vnfapp'].includes($route.path.split('/')[1])" style="margin-right: 5px">
            <resource-icon v-if="$showIcon() && record.icon && record.icon.base64image" :image="record.icon.base64image" size="2x"/>
            <os-logo v-else-if="record.ostypename" :osName="record.ostypename" size="2x" />
            <render-icon v-else-if="typeof $route.meta.icon ==='string'" style="font-size: 16px;" :icon="$route.meta.icon"/>
            <render-icon v-else style="font-size: 16px;" :svgIcon="$route.meta.icon" />
          </span>
          <span v-else :style="{ 'margin-right': record.ostypename ? '5px' : '0' }">
            <os-logo v-if="record.ostypename" :osName="record.ostypename" size="1x" />
          </span>

          <span v-if="record.hasannotations">
            <span v-if="record.id">
              <router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
              <router-link :to="{ path: $route.path + '/' + record.id, query: { tab: 'comments' } }"><message-filled style="padding-left: 10px" size="small"/></router-link>
            </span>
            <router-link v-else :to="{ path: $route.path + '/' + record.name }" >{{ text }}</router-link>
          </span>
          <span v-else-if="$route.path.startsWith('/globalsetting')">{{ text }}</span>
          <span v-else-if="$route.path.startsWith('/alert')">
            <router-link :to="{ path: $route.path + '/' + record.id }" v-if="record.id">{{ $t(text.toLowerCase()) }}</router-link>
            <router-link :to="{ path: $route.path + '/' + record.name }" v-else>{{ $t(text.toLowerCase()) }}</router-link>
          </span>
          <span v-else-if="$route.path.startsWith('/tungstenfabric')">
            <router-link :to="{ path: $route.path + '/' + record.id }" v-if="record.id">{{ $t(text.toLowerCase()) }}</router-link>
            <router-link :to="{ path: $route.path + '/' + record.name }" v-else>{{ $t(text.toLowerCase()) }}</router-link>
          </span>
          <span v-else-if="isTungstenPath()">
            <router-link :to="{ path: $route.path + '/' + record.uuid, query: { zoneid: record.zoneid } }" v-if="record.uuid && record.zoneid">{{ $t(text.toLowerCase()) }}</router-link>
            <router-link :to="{ path: $route.path + '/' + record.uuid, query: { zoneid: $route.query.zoneid } }" v-else-if="record.uuid && $route.query.zoneid">{{ $t(text.toLowerCase()) }}</router-link>
            <router-link :to="{ path: $route.path }" v-else>{{ $t(text.toLowerCase()) }}</router-link>
          </span>
          <span v-else>
            <router-link :to="{ path: $route.path + '/' + record.id }" v-if="record.id">{{ text }}</router-link>
            <router-link :to="{ path: $route.path + '/' + record.name }" v-else>{{ text }}</router-link>
          </span>
        </span>
      </template>
      <template v-if="column.key === 'templatetype'">
        <span>{{ text }}</span>
      </template>
      <template v-if="column.key === 'templateid'">
        <router-link :to="{ path: '/template/' + record.templateid }">{{ text }}</router-link>
      </template>
      <template v-if="column.key === 'type'">
        <span v-if="['USER.LOGIN', 'USER.LOGOUT', 'ROUTER.HEALTH.CHECKS', 'FIREWALL.CLOSE', 'ALERT.SERVICE.DOMAINROUTER'].includes(text)">{{ $t(text.toLowerCase()) }}</span>
        <span v-else>{{ text }}</span>
      </template>

      <template v-if="column.key === 'schedule'">
          {{ text }}
          <br/>
          ({{ generateHumanReadableSchedule(text) }})
      </template>
      <template v-if="column.key === 'displayname'">
        <QuickView
          style="margin-left: 5px"
          :actions="actions"
          :resource="record"
          :enabled="quickViewEnabled() && actions.length > 0 && columns && columns[0].dataIndex === 'displayname' "
          @exec-action="$parent.execAction"/>
        <router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
      </template>
      <template v-if="column.key === 'username'">
        <span v-if="$showIcon() && !['vm', 'vnfapp'].includes($route.path.split('/')[1])" style="margin-right: 5px">
          <resource-icon v-if="$showIcon() && record.icon && record.icon.base64image" :image="record.icon.base64image" size="2x"/>
          <user-outlined v-else style="font-size: 16px;" />
        </span>
        <router-link :to="{ path: $route.path + '/' + record.id }" v-if="['/accountuser', '/vpnuser'].includes($route.path)">{{ text }}</router-link>
        <router-link :to="{ path: '/accountuser', query: { username: record.username, domainid: record.domainid } }" v-else-if="$store.getters.userInfo.roletype !== 'User'">{{ text }}</router-link>
        <span v-else>{{ text }}</span>
      </template>
      <template v-if="column.key === 'entityid'">
        <router-link :to="{ path: generateCommentsPath(record), query: { tab: 'comments' } }">{{ record.entityname }}</router-link>
      </template>
      <template v-if="column.key === 'entitytype'">
        {{ generateHumanReadableEntityType(record) }}
      </template>
      <template v-if="column.key === 'adminsonly' && ['Admin'].includes($store.getters.userInfo.roletype)">
        <a-checkbox :checked="record.adminsonly" :value="record.id" v-if="record.userid === $store.getters.userInfo.id" @change="e => updateAdminsOnly(e)" />
        <a-checkbox :checked="record.adminsonly" disabled v-else />
      </template>
      <template v-if="column.key === 'ipaddress'" href="javascript:;">
        <router-link v-if="['/publicip', '/privategw'].includes($route.path)" :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
        <span v-else>
          <copy-label :label="text" />
        </span>
        <span v-if="record.issourcenat">
          &nbsp;
          <a-tag>source-nat</a-tag>
        </span>
        <span v-if="record.isstaticnat">
          &nbsp;
          <a-tag>static-nat</a-tag>
        </span>
      </template>
      <template v-if="column.key === 'ip6address'" href="javascript:;">
        <span>{{ ipV6Address(text, record) }}</span>
      </template>
      <template v-if="column.key === 'publicip'">
        <router-link v-if="['/autoscalevmgroup'].includes($route.path)" :to="{ path: '/publicip' + '/' + record.publicipid }">{{ text }}</router-link>
        <router-link v-else :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
      </template>
      <template v-if="column.key === 'traffictype'">
        {{ text }}
      </template>
      <template v-if="column.key === 'vmname'">
        <router-link :to="{ path: createPathBasedOnVmType(record.vmtype, record.virtualmachineid) }">{{ text }}</router-link>
      </template>
      <template v-if="column.key === 'virtualmachinename'">
        <router-link :to="{ path: getVmRouteUsingType(record) + record.virtualmachineid }">{{ text }}</router-link>
      </template>
      <template v-if="column.key === 'volumename'">
        <router-link v-if="resourceIdToValidLinksMap[record.id]?.volume" :to="{ path: '/volume/' + record.volumeid }">{{ text }}</router-link>
        <span v-else>{{ text }}</span>
      </template>
      <template v-if="record.clustertype === 'ExternalManaged' && $route.path.split('/')[1] === 'kubernetes' && ['kubernetesversionname', 'cpunumber', 'memory', 'size'].includes(column.key)">
        <span>{{ text <= 0 || !text ? 'N/A' : text }}</span>
      </template>
      <template v-else-if="column.key === 'size'">
        <span v-if="text && $route.path === '/kubernetes'">
          {{ text }}
        </span>
        <span v-else-if="text">
          {{ parseFloat(parseFloat(text) / 1024.0 / 1024.0 / 1024.0).toFixed(2) }} GiB
        </span>
      </template>
      <template v-if="column.key === 'physicalsize'">
        <span v-if="text">
          {{ isNaN(text) ? text : (parseFloat(parseFloat(text) / 1024.0 / 1024.0 / 1024.0).toFixed(2) + ' GiB') }}
        </span>
      </template>
      <template v-if="column.key === 'physicalnetworkname'">
        <router-link :to="{ path: '/physicalnetwork/' + record.physicalnetworkid }">{{ text }}</router-link>
      </template>
      <template v-if="column.key === 'serviceofferingname'">
        <router-link :to="{ path: '/computeoffering/' + record.serviceofferingid }">{{ text }}</router-link>
      </template>
      <template v-if="column.key === 'hypervisor'">
        <span v-if="$route.name === 'hypervisorcapability'">
          <router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
        </span>
        <span v-else-if="$route.name === 'guestoshypervisormapping'">
          <QuickView
            style="margin-left: 5px"
            :actions="actions"
            :resource="record"
            :enabled="quickViewEnabled() && actions.length > 0 && columns && columns[0].dataIndex === 'hypervisor' "
            @exec-action="$parent.execAction"/>
          <router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
        </span>
        <span v-else>{{ text }}</span>
      </template>
      <template v-if="column.key === 'osname'">
        <span v-if="$route.name === 'guestos'">
          <router-link :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
        </span>
        <span v-else>{{ text }}</span>
      </template>
      <template v-if="column.key === 'state'">
        <status v-if="$route.path.startsWith('/host')" :text="getHostState(record)" displayText />
        <status v-else :text="text ? text : ''" displayText :styles="{ 'min-width': '80px' }" />
      </template>
      <template v-if="column.key === 'status'">
        <status :text="text ? text : ''" displayText />
      </template>
      <template v-if="column.key === 'allocationstate'">
        <status :text="text ? text : ''" displayText />
      </template>
      <template v-if="column.key === 'resourcestate'">
        <status :text="text ? text : ''" displayText />
      </template>
      <template v-if="column.key === 'powerstate'">
        <status :text="text ? text : ''" displayText />
      </template>
      <template v-if="column.key === 'agentstate'">
        <status :text="text ? text : ''" displayText />
      </template>
      <template v-if="column.key === 'quotastate'">
        <status :text="text ? text : ''" displayText />
      </template>
      <template v-if="column.key === 'vlan'">
        <a href="javascript:;">
          <router-link v-if="$route.path === '/guestvlans'" :to="{ path: '/guestvlans/' + record.id }">{{ text }}</router-link>
        </a>
      </template>
      <template v-if="column.key === 'guestnetworkname'">
        <router-link :to="{ path: '/guestnetwork/' + record.guestnetworkid }">{{ text }}</router-link>
      </template>
      <template v-if="column.key === 'associatednetworkname'">
        <router-link :to="{ path: '/guestnetwork/' + record.associatednetworkid }">{{ text }}</router-link>
      </template>
      <template v-if="column.key === 'vpcname'">
        <a v-if="record.vpcid">
          <router-link :to="{ path: '/vpc/' + record.vpcid }">{{ text || record.vpcid }}</router-link>
        </a>
        <span v-else>{{ text }}</span>
      </template>
      <template v-if="column.key === 'hostname'">
        <router-link v-if="record.hostid" :to="{ path: '/host/' + record.hostid }">{{ text }}</router-link>
        <router-link v-else-if="record.hostname" :to="{ path: $route.path + '/' + record.id }">{{ text }}</router-link>
        <span v-else>{{ text }}</span>
      </template>
      <template v-if="column.key === 'storage'">
        <router-link v-if="record.storageid" :to="{ path: '/storagepool/' + record.storageid }">{{ text }}</router-link>
        <span v-else>{{ text }}</span>
      </template>
      <template v-for="(value, name) in thresholdMapping" :key="name">
        <template v-if="column.key === name">
          <span>
            <span v-if="record[value.disable]" class="alert-disable-threshold">
              {{ text }}
            </span>
            <span v-else-if="record[value.notification]" class="alert-notification-threshold">
              {{ text }}
            </span>
            <span style="padding: 10%;" v-else>
              {{ text }}
            </span>
          </span>
        </template>
      </template>
      <template v-if="column.key === 'level'">
        <router-link :to="{ path: '/event/' + record.id }">{{ text }}</router-link>
      </template>
      <template v-if="column.key === 'usageType'">
        {{ usageTypeMap[record.usagetype] }}
      </template>

      <template v-if="column.key === 'clustername'">
        <router-link :to="{ path: '/cluster/' + record.clusterid }">{{ text }}</router-link>
      </template>
      <template v-if="column.key === 'objectstore'">
        <router-link :to="{ path: '/objectstore/' + record.objectstorageid }">{{ text }}</router-link>
      </template>
      <template v-if="column.key === 'podname'">
        <router-link :to="{ path: '/pod/' + record.podid }">{{ text }}</router-link>
      </template>
      <template v-if="column.key === 'account'">
        <template v-if="record.owner">
          <template v-for="(item, idx) in record.owner" :key="idx">
            <span style="margin-right:5px">
              <span v-if="$store.getters.userInfo.roletype !== 'User'">
                <router-link v-if="'user' in item" :to="{ path: '/accountuser', query: { username: item.user, domainid: record.domainid }}">{{ item.account + '(' + item.user + ')' }}</router-link>
                <router-link v-else :to="{ path: '/account', query: { name: item.account, domainid: record.domainid, dataView: true } }">{{ item.account }}</router-link>
              </span>
              <span v-else>{{ item.user ? item.account + '(' + item.user + ')' : item.account }}</span>
            </span>
          </template>
        </template>
        <template v-if="text && !text.startsWith('PrjAcct-')">
          <router-link
            v-if="'quota' in record && $router.resolve(`${$route.path}/${record.account}`).matched[0].redirect !== '/exception/404'"
            :to="{ path: `${$route.path}/${record.account}`, query: { account: record.account, domainid: record.domainid, quota: true } }">{{ text }}</router-link>
          <router-link :to="{ path: '/account/' + record.accountid }" v-else-if="record.accountid">{{ text }}</router-link>
          <router-link :to="{ path: '/account', query: { name: record.account, domainid: record.domainid, dataView: true } }" v-else-if="$store.getters.userInfo.roletype !== 'User'">{{ text }}</router-link>
          <span v-else>{{ text }}</span>
        </template>
      </template>
      <template v-if="column.key === 'resource'">
        <resource-label :resourceType="record.resourcetype" :resourceId="record.resourceid" :resourceName="record.resourcename" />
      </template>
      <template v-if="column.key === 'domain'">
        <router-link v-if="record.domainid && !record.domainid.toString().includes(',') && $store.getters.userInfo.roletype !== 'User'" :to="{ path: '/domain/' + record.domainid, query: { tab: 'details' } }">{{ text }}</router-link>
        <span v-else>{{ text }}</span>
      </template>
      <template v-if="column.key === 'domainpath'">
        <router-link v-if="record.domainid && !record.domainid.includes(',') && $router.resolve('/domain/' + record.domainid).matched[0].redirect !== '/exception/404'" :to="{ path: '/domain/' + record.domainid, query: { tab: 'details' } }">{{ text }}</router-link>
        <span v-else>{{ text }}</span>
      </template>
      <template v-if="column.key === 'zone'">
        <router-link v-if="record.zoneid && !record.zoneid.includes(',') && $router.resolve('/zone/' + record.zoneid).matched[0].redirect !== '/exception/404'" :to="{ path: '/zone/' + record.zoneid }">{{ text || record.zoneid }}</router-link>
        <span v-else>{{ text }}</span>
      </template>
      <template v-if="column.key === 'zonename'">
        <router-link v-if="$router.resolve('/zone/' + record.zoneid).matched[0].redirect !== '/exception/404'" :to="{ path: '/zone/' + record.zoneid }">{{ text }}</router-link>
        <router-link v-else-if="$router.resolve('/zones/' + record.zoneid).matched[0].redirect !== '/exception/404'" :to="{ path: '/zones/' + record.zoneid }">{{ text }}</router-link>
        <span v-else>{{ text }}</span>
      </template>
      <template v-if="column.key === 'rolename'">
        <router-link v-if="record.roleid && $router.resolve('/role/' + record.roleid).matched[0].redirect !== '/exception/404'" :to="{ path: '/role/' + record.roleid }">{{ text }}</router-link>
        <span v-else>{{ text }}</span>
      </template>
      <template v-if="column.key === 'project'">
        <router-link v-if="$router.resolve('/project/' + record.projectid).matched[0].redirect !== '/exception/404'" :to="{ path: '/project/' + record.projectid }">{{ text }}</router-link>
        <span v-else>{{ text }}</span>
      </template>
      <template v-if="column.key === 'templateversion'">
        <span>  {{ record.version }} </span>
      </template>
      <template v-if="column.key === 'drsimbalance'">
        <span>  {{ record.drsimbalance }} </span>
      </template>
      <template v-if="column.key === 'softwareversion'">
        <span>  {{ record.softwareversion ? record.softwareversion : 'N/A' }} </span>
      </template>
      <template v-if="column.key === 'readonly'">
        <status :text="record.readonly ? 'ReadOnly' : 'ReadWrite'" displayText />
      </template>
      <template v-if="column.key === 'requiresupgrade'">
        <status :text="record.requiresupgrade ? 'warning' : ''" />
        {{ record.requiresupgrade ? 'Yes' : 'No' }}
      </template>
      <template v-if="column.key === 'loadbalancerrule'">
        <span>  {{ record.loadbalancerrule }} </span>
      </template>
      <template v-if="column.key === 'autoscalingenabled'">
        <status :text="record.autoscalingenabled ? 'Enabled' : 'Disabled'" />
        {{ record.autoscalingenabled ? 'Enabled' : 'Disabled' }}
      </template>
      <template v-if="column.key === 'current'">
        <status :text="record.current ? record.current.toString() : 'false'" />
      </template>
      <template v-if="column.key === 'enabled'">
        <status :text="record.enabled ? record.enabled.toString() : 'false'" />
        {{ record.enabled ? 'Enabled' : 'Disabled' }}
      </template>
      <template v-if="['created', 'sent'].includes(column.key) || (['startdate'].includes(column.key) && ['webhook'].includes($route.path.split('/')[1]))">
        {{ $toLocaleDate(text) }}
      </template>
      <template v-if="['startdate', 'enddate'].includes(column.key) && ['vm', 'vnfapp'].includes($route.path.split('/')[1])">
        {{ getDateAtTimeZone(text, record.timezone) }}
      </template>
      <template v-if="column.key === 'payloadurl'">
        <copy-label :label="text" />
      </template>
      <template v-if="column.key === 'usageid'">
        <copy-label :label="text" />
      </template>
      <template v-if="column.key === 'eventtype'">
        <router-link v-if="$router.resolve('/event/' + record.eventid).matched[0].redirect !== '/exception/404'" :to="{ path: '/event/' + record.eventid }">{{ text }}</router-link>
        <span v-else>{{ text }}</span>
      </template>
      <template v-if="column.key === 'managementservername'">
        <router-link v-if="$router.resolve('/managementserver/' + record.managementserverid).matched[0].redirect !== '/exception/404'" :to="{ path: '/managementserver/' + record.managementserverid }">{{ text }}</router-link>
        <router-link v-else-if="$router.resolve('/managementservers/' + record.managementserverid).matched[0].redirect !== '/exception/404'" :to="{ path: '/managementservers/' + record.managementserverid }">{{ text }}</router-link>
        <span v-else>{{ text }}</span>
      </template>
      <template v-if="column.key === 'payload'">
        <router-link v-if="$router.resolve('/webhookdeliveries/' + record.id).matched[0].redirect !== '/exception/404'" :to="{ path: '/webhookdeliveries/' + record.id }">{{ getTrimmedText(text, 48) }}</router-link>
        <span v-else>  {{ getTrimmedText(text, 48) }} </span>
        <QuickView
          style="margin-left: 5px"
          :actions="actions"
          :resource="record"
          :enabled="quickViewEnabled() && actions.length > 0"
          @exec-action="$parent.execAction"/>
      </template>
      <template v-if="column.key === 'webhookname'">
        <router-link v-if="$router.resolve('/webhook/' + record.webhookid).matched[0].redirect !== '/exception/404'" :to="{ path: '/webhook/' + record.webhookid }">{{ text }}</router-link>
        <span v-else>  {{ text }} </span>
      </template>
      <template v-if="column.key === 'success'">
        <status :text="text ? 'success' : 'error'" />
      </template>
      <template v-if="column.key === 'response'">
        <span>  {{ getTrimmedText(text, 48) }} </span>
      </template>
      <template v-if="column.key === 'duration' && ['webhook', 'webhookdeliveries'].includes($route.path.split('/')[1])">
        <span>  {{ getDuration(record.startdate, record.enddate) }} </span>
      </template>
      <template v-if="['startdate', 'enddate'].includes(column.key) && ['usage'].includes($route.path.split('/')[1])">
        {{ $toLocaleDate(text.replace('\'T\'', ' ')) }}
      </template>
      <template v-if="column.key === 'order'">
        <div class="shift-btns">
          <a-tooltip :name="text" placement="top">
            <template #title>{{ $t('label.move.to.top') }}</template>
            <a-button
              shape="round"
              @click="moveItemTop(record)"
              class="shift-btn">
              <DoubleLeftOutlined class="shift-btn shift-btn--rotated" />
            </a-button>
          </a-tooltip>
          <a-tooltip placement="top">
            <template #title>{{ $t('label.move.to.bottom') }}</template>
            <a-button
              shape="round"
              @click="moveItemBottom(record)"
              class="shift-btn">
              <DoubleRightOutlined class="shift-btn shift-btn--rotated" />
            </a-button>
          </a-tooltip>
          <a-tooltip placement="top">
            <template #title>{{ $t('label.move.up.row') }}</template>
            <a-button shape="round" @click="moveItemUp(record)" class="shift-btn">
              <CaretUpOutlined class="shift-btn" />
            </a-button>
          </a-tooltip>
          <a-tooltip placement="top">
            <template #title>{{ $t('label.move.down.row') }}</template>
            <a-button shape="round" @click="moveItemDown(record)" class="shift-btn">
              <CaretDownOutlined class="shift-btn" />
            </a-button>
          </a-tooltip>
        </div>
      </template>

      <template v-if="column.key === 'value'">
        <a-input
          v-if="editableValueKey === record.key"
          v-focus="true"
          :defaultValue="record.value"
          :disabled="!('updateConfiguration' in $store.getters.apis)"
          v-model:value="editableValue"
          @keydown.esc="editableValueKey = null"
          @pressEnter="saveValue(record)">
        </a-input>
        <div v-else style="width: 200px; word-break: break-all">
          {{ text }}
        </div>
      </template>
      <template v-if="column.key === 'actions'">
        <tooltip-button
          :tooltip="$t('label.edit')"
          :disabled="!('updateConfiguration' in $store.getters.apis)"
          v-if="editableValueKey !== record.key"
          icon="edit-outlined"
          @onClick="editValue(record)" />
        <tooltip-button
          :tooltip="$t('label.cancel')"
          @onClick="editableValueKey = null"
          v-if="editableValueKey === record.key"
          iconType="CloseCircleTwoTone"
          iconTwoToneColor="#f5222d" />
        <tooltip-button
          :tooltip="$t('label.ok')"
          :disabled="!('updateConfiguration' in $store.getters.apis)"
          @onClick="saveValue(record)"
          v-if="editableValueKey === record.key"
          iconType="CheckCircleTwoTone"
          iconTwoToneColor="#52c41a" />
        <tooltip-button
          :tooltip="$t('label.reset.config.value')"
          @onClick="resetConfig(record)"
          v-if="editableValueKey !== record.key"
          icon="reload-outlined"
          :disabled="!('updateConfiguration' in $store.getters.apis)" />
      </template>
      <template v-if="column.key === 'usageActions'">
        <tooltip-button
          :tooltip="$t('label.view')"
          icon="search-outlined"
          @onClick="$emit('view-usage-record', record)" />
        <slot></slot>
      </template>
      <template v-if="column.key === 'tariffActions'">
        <tooltip-button
          :tooltip="$t('label.edit')"
          v-if="editableValueKey !== record.key"
          :disabled="!('quotaTariffUpdate' in $store.getters.apis)"
          icon="edit-outlined"
          @onClick="editTariffValue(record)" />
        <slot></slot>
      </template>
      <template v-if="column.key === 'vmScheduleActions'">
        <tooltip-button
          :tooltip="$t('label.edit')"
          :disabled="!('updateVMSchedule' in $store.getters.apis)"
          icon="edit-outlined"
          @onClick="updateVMSchedule(record)" />
        <tooltip-button
          :tooltip="$t('label.remove')"
          :disabled="!('deleteVMSchedule' in $store.getters.apis)"
          icon="delete-outlined"
          :danger="true"
          type="primary"
          @onClick="removeVMSchedule(record)" />
      </template>
    </template>
    <template #footer>
      <span v-if="hasSelected">
        {{ `Selected ${selectedRowKeys.length} items` }}
      </span>
    </template>
  </a-table>
</template>

<script>
import { api } from '@/api'
import OsLogo from '@/components/widgets/OsLogo'
import Status from '@/components/widgets/Status'
import QuickView from '@/components/view/QuickView'
import CopyLabel from '@/components/widgets/CopyLabel'
import TooltipButton from '@/components/widgets/TooltipButton'
import ResourceIcon from '@/components/view/ResourceIcon'
import ResourceLabel from '@/components/widgets/ResourceLabel'
import { createPathBasedOnVmType } from '@/utils/plugins'
import { validateLinks } from '@/utils/links'
import cronstrue from 'cronstrue/i18n'
import moment from 'moment-timezone'

export default {
  name: 'ListView',
  components: {
    OsLogo,
    Status,
    QuickView,
    CopyLabel,
    TooltipButton,
    ResourceIcon,
    ResourceLabel
  },
  props: {
    columns: {
      type: Array,
      required: true
    },
    columnKeys: {
      type: Array,
      default: () => []
    },
    selectedColumns: {
      type: Array,
      default: () => []
    },
    items: {
      type: Array,
      required: true
    },
    loading: {
      type: Boolean,
      default: false
    },
    actions: {
      type: Array,
      default: () => []
    },
    explicitlyAllowRowSelection: {
      type: Boolean,
      default: false
    }
  },
  inject: ['parentFetchData', 'parentToggleLoading'],
  data () {
    return {
      selectedRowKeys: [],
      editableValueKey: null,
      editableValue: '',
      resourceIcon: '',
      thresholdMapping: {
        cpuused: {
          notification: 'cputhreshold',
          disable: 'cpudisablethreshold'
        },
        cpuallocated: {
          notification: 'cpuallocatedthreshold',
          disable: 'cpuallocateddisablethreshold'
        },
        memoryused: {
          notification: 'memorythreshold',
          disable: 'memorydisablethreshold'
        },
        memoryallocated: {
          notification: 'memoryallocatedthreshold',
          disable: 'memoryallocateddisablethreshold'
        },
        cpuusedghz: {
          notification: 'cputhreshold',
          disable: 'cpudisablethreshold'
        },
        cpuallocatedghz: {
          notification: 'cpuallocatedthreshold',
          disable: 'cpuallocateddisablethreshold'
        },
        memoryusedgb: {
          notification: 'memorythreshold',
          disable: 'memorydisablethreshold'
        },
        memoryallocatedgb: {
          notification: 'memoryallocatedthreshold',
          disable: 'memoryallocateddisablethreshold'
        },
        disksizeusedgb: {
          notification: 'storageusagethreshold',
          disable: 'storageusagedisablethreshold'
        },
        disksizeallocatedgb: {
          notification: 'storageallocatedthreshold',
          disable: 'storageallocateddisablethreshold'
        }
      },
      usageTypeMap: {},
      resourceIdToValidLinksMap: {}
    }
  },
  watch: {
    items: {
      deep: true,
      handler (newData, oldData) {
        if (newData === oldData) return
        this.items.forEach(record => {
          this.resourceIdToValidLinksMap[record.id] = validateLinks(this.$router, false, record)
        })
      }
    }
  },
  created () {
    this.getUsageTypes()
  },
  computed: {
    hasSelected () {
      return this.selectedRowKeys.length > 0
    }
  },
  methods: {
    isTungstenPath () {
      return ['/tungstennetworkroutertable', '/tungstenpolicy', '/tungsteninterfaceroutertable',
        '/tungstenpolicyset', '/tungstenroutingpolicy', '/firewallrule', '/tungstenfirewallpolicy'].includes(this.$route.path)
    },
    createPathBasedOnVmType: createPathBasedOnVmType,
    quickViewEnabled () {
      return new RegExp(['/vm', '/kubernetes', '/ssh', '/userdata', '/vmgroup', '/affinitygroup', '/autoscalevmgroup',
        '/volume', '/snapshot', '/vmsnapshot', '/backup',
        '/guestnetwork', '/vpc', '/vpncustomergateway', '/vnfapp',
        '/template', '/iso',
        '/project', '/account', 'buckets', 'objectstore',
        '/zone', '/pod', '/cluster', '/host', '/storagepool', '/imagestore', '/systemvm', '/router', '/ilbvm', '/annotation',
        '/computeoffering', '/systemoffering', '/diskoffering', '/backupoffering', '/networkoffering', '/vpcoffering',
        '/tungstenfabric', '/oauthsetting', '/guestos', '/guestoshypervisormapping', '/webhook', 'webhookdeliveries'].join('|'))
        .test(this.$route.path)
    },
    enableGroupAction () {
      return ['vm', 'alert', 'vmgroup', 'ssh', 'userdata', 'affinitygroup', 'autoscalevmgroup', 'volume', 'snapshot',
        'vmsnapshot', 'backup', 'guestnetwork', 'vpc', 'publicip', 'vpnuser', 'vpncustomergateway', 'vnfapp',
        'project', 'account', 'systemvm', 'router', 'computeoffering', 'systemoffering',
        'diskoffering', 'backupoffering', 'networkoffering', 'vpcoffering', 'ilbvm', 'kubernetes', 'comment', 'buckets',
        'webhook', 'webhookdeliveries'
      ].includes(this.$route.name)
    },
    getDateAtTimeZone (date, timezone) {
      return date ? moment(date).tz(timezone).format('YYYY-MM-DD HH:mm:ss') : null
    },
    fetchColumns () {
      if (this.isOrderUpdatable()) {
        return this.columns
      }
      return this.columns.filter(x => x.dataIndex !== 'order')
    },
    getRowClassName (record, index) {
      if (index % 2 === 0) {
        return 'light-row'
      }
      return 'dark-row'
    },
    setSelection (selection) {
      this.selectedRowKeys = selection
      this.$emit('selection-change', this.selectedRowKeys)
    },
    resetSelection () {
      this.setSelection([])
    },
    onSelectChange (selectedRowKeys, selectedRows) {
      this.setSelection(selectedRowKeys)
    },
    changeProject (project) {
      this.$store.dispatch('SetProject', project)
      this.$store.dispatch('ToggleTheme', project.id === undefined ? 'light' : 'dark')
      this.$message.success(this.$t('message.switch.to') + ' ' + project.name)
      this.$router.push({ name: 'dashboard' })
    },
    saveValue (record) {
      api('updateConfiguration', {
        name: record.name,
        value: this.editableValue
      }).then(json => {
        this.editableValueKey = null
        this.$store.dispatch('RefreshFeatures')
        this.$message.success(`${this.$t('message.setting.updated')} ${record.name}`)
        if (json.updateconfigurationresponse &&
          json.updateconfigurationresponse.configuration &&
          !json.updateconfigurationresponse.configuration.isdynamic &&
          ['Admin'].includes(this.$store.getters.userInfo.roletype)) {
          this.$notification.warning({
            message: this.$t('label.status'),
            description: this.$t('message.restart.mgmt.server')
          })
        }
      }).catch(error => {
        console.error(error)
        this.$message.error(this.$t('message.error.save.setting'))
      }).finally(() => {
        this.$emit('refresh')
      })
    },
    resetConfig (item) {
      api('resetConfiguration', {
        name: item.name
      }).then(() => {
        const message = `${this.$t('label.setting')} ${item.name} ${this.$t('label.reset.config.value')}`
        this.$message.success(message)
      }).catch(error => {
        console.error(error)
        this.$message.error(this.$t('message.error.reset.config'))
        this.$notification.error({
          message: this.$t('label.error'),
          description: this.$t('message.error.reset.config')
        })
      }).finally(() => {
        this.$emit('refresh')
      })
    },
    editValue (record) {
      this.editableValueKey = record.key
      this.editableValue = record.value
    },
    getUpdateApi () {
      let apiString = ''
      switch (this.$route.name) {
        case 'template':
          apiString = 'updateTemplate'
          break
        case 'iso':
          apiString = 'updateIso'
          break
        case 'zone':
          apiString = 'updateZone'
          break
        case 'computeoffering':
        case 'systemoffering':
          apiString = 'updateServiceOffering'
          break
        case 'diskoffering':
          apiString = 'updateDiskOffering'
          break
        case 'networkoffering':
          apiString = 'updateNetworkOffering'
          break
        case 'vpcoffering':
          apiString = 'updateVPCOffering'
          break
        default:
          apiString = 'updateTemplate'
      }
      return apiString
    },
    isOrderUpdatable () {
      return this.getUpdateApi() in this.$store.getters.apis
    },
    handleUpdateOrder (id, index) {
      this.parentToggleLoading()
      const apiString = this.getUpdateApi()

      return new Promise((resolve, reject) => {
        api(apiString, {
          id,
          sortKey: index
        }).then((response) => {
          resolve(response)
        }).catch((reason) => {
          reject(reason)
        })
      })
    },
    updateOrder (data) {
      const promises = []
      data.forEach((item, index) => {
        promises.push(this.handleUpdateOrder(item.id, index + 1))
      })
      Promise.all(promises).catch((reason) => {
        console.log(reason)
      }).finally(() => {
        this.parentToggleLoading()
        this.parentFetchData()
      })
    },
    moveItemUp (record) {
      const data = this.items
      const index = data.findIndex(item => item.id === record.id)
      if (index === 0) return
      data.splice(index - 1, 0, data.splice(index, 1)[0])
      this.updateOrder(data)
    },
    moveItemDown (record) {
      const data = this.items
      const index = data.findIndex(item => item.id === record.id)
      if (index === data.length - 1) return
      data.splice(index + 1, 0, data.splice(index, 1)[0])
      this.updateOrder(data)
    },
    moveItemTop (record) {
      const data = this.items
      const index = data.findIndex(item => item.id === record.id)
      if (index === 0) return
      data.unshift(data.splice(index, 1)[0])
      this.updateOrder(data)
    },
    moveItemBottom (record) {
      const data = this.items
      const index = data.findIndex(item => item.id === record.id)
      if (index === data.length - 1) return
      data.push(data.splice(index, 1)[0])
      this.updateOrder(data)
    },
    editTariffValue (record) {
      this.$emit('edit-tariff-action', true, record)
    },
    updateVMSchedule (record) {
      this.$emit('update-vm-schedule', record)
    },
    removeVMSchedule (record) {
      this.$emit('remove-vm-schedule', record)
    },
    ipV6Address (text, record) {
      if (!record || !record.nic || record.nic.length === 0) {
        return ''
      }

      return record.nic.filter(e => { return e.ip6address }).map(e => { return e.ip6address }).join(', ') || text
    },
    generateCommentsPath (record) {
      if (this.entityTypeToPath(record.entitytype) === 'ssh') {
        return '/' + this.entityTypeToPath(record.entitytype) + '/' + record.entityname
      }
      return '/' + this.entityTypeToPath(record.entitytype) + '/' + record.entityid
    },
    generateHumanReadableEntityType (record) {
      switch (record.entitytype) {
        case 'VM' : return 'Virtual Machine'
        case 'HOST' : return 'Host'
        case 'VOLUME' : return 'Volume'
        case 'SNAPSHOT' : return 'Snapshot'
        case 'VM_SNAPSHOT' : return 'VM Snapshot'
        case 'INSTANCE_GROUP' : return 'Instance Group'
        case 'NETWORK' : return 'Network'
        case 'VPC' : return 'VPC'
        case 'PUBLIC_IP_ADDRESS' : return 'Public IP Address'
        case 'VPN_CUSTOMER_GATEWAY' : return 'VPC Customer Gateway'
        case 'TEMPLATE' : return 'Template'
        case 'ISO' : return 'ISO'
        case 'SSH_KEYPAIR' : return 'SSH Key Pair'
        case 'DOMAIN' : return 'Domain'
        case 'SERVICE_OFFERING' : return 'Service Offfering'
        case 'DISK_OFFERING' : return 'Disk Offering'
        case 'NETWORK_OFFERING' : return 'Network Offering'
        case 'POD' : return 'Pod'
        case 'ZONE' : return 'Zone'
        case 'CLUSTER' : return 'Cluster'
        case 'PRIMARY_STORAGE' : return 'Primary Storage'
        case 'SECONDARY_STORAGE' : return 'Secondary Storage'
        case 'VR' : return 'Virtual Router'
        case 'SYSTEM_VM' : return 'System VM'
        case 'KUBERNETES_CLUSTER': return 'Kubernetes Cluster'
        case 'AUTOSCALE_VM_GROUP': return 'AutoScale VM group'
        default: return record.entitytype.toLowerCase().replace('_', '')
      }
    },
    generateHumanReadableSchedule (schedule) {
      return cronstrue.toString(schedule, { locale: this.$i18n.locale })
    },
    entityTypeToPath (entitytype) {
      switch (entitytype) {
        case 'VM' : return 'vm'
        case 'HOST' : return 'host'
        case 'VOLUME' : return 'volume'
        case 'SNAPSHOT' : return 'snapshot'
        case 'VM_SNAPSHOT' : return 'vmsnapshot'
        case 'INSTANCE_GROUP' : return 'vmgroup'
        case 'NETWORK' : return 'guestnetwork'
        case 'VPC' : return 'vpc'
        case 'PUBLIC_IP_ADDRESS' : return 'publicip'
        case 'VPN_CUSTOMER_GATEWAY' : return 'vpncustomergateway'
        case 'TEMPLATE' : return 'template'
        case 'ISO' : return 'iso'
        case 'SSH_KEYPAIR' : return 'ssh'
        case 'DOMAIN' : return 'domain'
        case 'SERVICE_OFFERING' : return 'computeoffering'
        case 'DISK_OFFERING' : return 'diskoffering'
        case 'NETWORK_OFFERING' : return 'networkoffering'
        case 'POD' : return 'pod'
        case 'ZONE' : return 'zone'
        case 'CLUSTER' : return 'cluster'
        case 'PRIMARY_STORAGE' : return 'storagepool'
        case 'SECONDARY_STORAGE' : return 'imagestore'
        case 'VR' : return 'router'
        case 'SYSTEM_VM' : return 'systemvm'
        case 'KUBERNETES_CLUSTER': return 'kubernetes'
        case 'AUTOSCALE_VM_GROUP': return 'autoscalevmgroup'
        default: return entitytype.toLowerCase().replace('_', '')
      }
    },
    updateAdminsOnly (e) {
      api('updateAnnotationVisibility', {
        id: e.target.value,
        adminsonly: e.target.checked
      }).finally(() => {
        const data = this.items
        const index = data.findIndex(item => item.id === e.target.value)
        const elem = data[index]
        elem.adminsonly = e.target.checked
      })
    },
    getHostState (host) {
      if (host && host.hypervisor === 'KVM' && host.state === 'Up' && host.details && host.details.secured !== 'true') {
        return 'Unsecure'
      }
      return host.state
    },
    getColumnKey (name) {
      if (typeof name === 'object') {
        name = Object.keys(name).includes('field') ? name.field : name.customTitle
      }
      return name
    },
    getColumTitle (name) {
      if (typeof name === 'object') {
        name = Object.keys(name).includes('customTitle') ? name.customTitle : name.field
      }
      return name
    },
    handleResizeColumn (w, col) {
      col.width = w
    },
    updateSelectedColumns (name) {
      this.$emit('update-selected-columns', name)
    },
    getVmRouteUsingType (record) {
      switch (record.virtualmachinetype) {
        case 'DomainRouter' : return '/router/'
        case 'ConsoleProxy' :
        case 'SecondaryStorageVm': return '/systemvm/'
        default: return '/vm/'
      }
    },
    getTrimmedText (text, length) {
      if (!text) {
        return ''
      }
      return (text.length <= length) ? text : (text.substring(0, length - 3) + '...')
    },
    getDuration (startdate, enddate) {
      if (!startdate || !enddate) {
        return ''
      }
      var duration = Date.parse(enddate) - Date.parse(startdate)
      return (duration > 0 ? duration / 1000.0 : 0) + ''
    },
    getUsageTypes () {
      if (this.$route.path.split('/')[1] === 'usage') {
        api('listUsageTypes').then(json => {
          if (json && json.listusagetypesresponse && json.listusagetypesresponse.usagetype) {
            this.usageTypes = json.listusagetypesresponse.usagetype.map(x => {
              return {
                id: x.usagetypeid,
                value: x.description
              }
            })
            this.usageTypeMap = {}
            for (var usageType of this.usageTypes) {
              this.usageTypeMap[usageType.id] = usageType.value
            }
          }
        })
      }
    }
  }
}
</script>

<style>
:deep(.ant-table-thead) {
  background-color: #f9f9f9;
}

:deep(.ant-table-small) > .ant-table-content > .ant-table-body {
  margin: 0;
}

:deep(.ant-table-tbody)>tr>td, :deep(.ant-table-thead)>tr>th {
  overflow-wrap: anywhere;
}

.filter-dropdown .ant-menu-vertical {
  border: none;
}

.filter-dropdown .ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
  background-color: transparent;
}
</style>

<style scoped lang="scss">
  .shift-btns {
    display: flex;
  }
  .shift-btn {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 20px;
    height: 20px;
    font-size: 12px;

    &:not(:last-child) {
      margin-right: 5px;
    }

    &--rotated {
      font-size: 10px;
      transform: rotate(90deg);
    }

  }

  .alert-notification-threshold {
    background-color: rgba(255, 231, 175, 0.75);
    color: #e87900;
    padding: 10%;
  }

  .alert-disable-threshold {
    background-color: rgba(255, 190, 190, 0.75);
    color: #f50000;
    padding: 10%;
  }
</style>
